<?php

namespace app\api\controller\paotui;

use addons\paotui\library\SnowFlake;
use app\admin\model\paotui\PostSocket;
use app\admin\model\paotui\Third;
use app\common\controller\Api;
use think\Db;
use think\Exception;
use think\Validate;
use Yansongda\Pay\Pay;

/**
 * 快递接口
 */
class Post extends Api
{

    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['market_info'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = "*";

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 快递列表
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function index(){
        $status = $this->request->post("type",'');
        $page = $this->request->post('page',0);
        $limit = $this->request->post('limit',0);

        $userModel = new \app\admin\model\User();
        $userInfo = $userModel->where(['id'=>$this->auth->id])->find();

        $user_id = $this->auth->id;
        $mobile = $userInfo['mobile'];

        $where = function ($query) use ($user_id,$mobile){
            $query->where(function ($query) use ($mobile){
                $query->where(['to_mobile'=>[['eq',$mobile],['neq','']],'pay_status'=>1]);
            })
                ->whereOr(['user_id'=>$user_id]);
        };
        $postService = new \addons\paotui\service\Post();
        $data = $postService->getPostList($status,$where,$page,$limit,"*","id desc");
        foreach ($data['data'] as &$v){
            $v['from_or_to'] = ($v['user_id'] == $this->auth->id)?'from':'to';
        }
        $this->success('请求成功',$data);
    }

    /**
     * 快递详情
     * @throws Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function info(){
        $order_no = $this->request->post("order_no",'');

        $postService = new \addons\paotui\service\Post();
        $data = $postService->getInfoByUser($order_no,$this->auth->id);
        $this->success('请求成功',$data);
    }

    /**
     * 公开的快递详情
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function market_info(){
        $order_no = $this->request->post("order_no",'');

        $postService = new \addons\paotui\service\Post();
        $postInfo = $postService->getInfoByMarket($order_no);
        if(empty($postInfo)){
            $this->error('当前快递不存在');
        }

        if($postInfo['user_id'] == $this->auth->id){
            $postInfo['is_owner'] = 1;
        }else{
            $postInfo['is_owner'] = 0;
        }
        $this->success('操作成功',$postInfo);
    }


    /**
     * 获取支付金额
     */
    public function payPrice(){

        $from_address_id = $this->request->post("from_address_id");
        $to_address_id = $this->request->post("to_address_id");
        $type = $this->request->post('type',1);
        $weight = $this->request->post('weight',5);

        $postService = new \addons\paotui\service\Post();
        $return = $postService->getPostDetailPrice($from_address_id,$to_address_id,$this->auth->id,$type,$weight);
        if($return){
            $this->success("请求成功",$return);
        }else{
            $this->error($postService->error);
        }
    }

    /**
     * 发快递
     */
    public function add(){
        $from_address_id = $this->request->post("from_address_id");
        $to_address_id = $this->request->post("to_address_id");
        $type = $this->request->post('type',1);
        $goods_type = $this->request->post('goods_type',1);
        $weight = $this->request->post('weight',5);
        $b_true_price = $this->request->post('b_price',0);
        $tips_price = $this->request->post('tips_price',0);     //小费

        $is_appoints = $this->request->post('is_appoints',0);
        $appoints_day = $this->request->post('appoints_day',"");
        $appoints_time = $this->request->post('appoints_time',"");

        $note = $this->request->post("note","");

        #判断收发件地址是否正确 start#
        $userAddress = new \addons\paotui\service\UserAddress();
        $fromAddress = $userAddress->getAddressInfo($from_address_id,$this->auth->id);
        if(empty($fromAddress)){
            $this->error('请选择正确的发件地址');
        }

        $toAddress = $userAddress->getAddressInfo($to_address_id,$this->auth->id);
        if(empty($toAddress)){
            $this->error('请选择正确的收件地址');
        }
        #判断收发件地址是否正确 end#

        #获取保价金额 start#
        if($b_true_price){
            $b_price = $b_true_price;
        }else{
            $b_price = 0;
        }
        #获取保价金额 end#


        $order_code = SnowFlake::generateId();  //获取订单编号

        $data['order_no'] = $order_code;        //订单号
        $data['user_id'] = $this->auth->id;
        $data['type'] = $type;

        $data['from_address_id'] = $fromAddress['id'];
        $data['from_province'] = $fromAddress['province'];
        $data['from_city'] = $fromAddress['city'];
        $data['from_district'] = $fromAddress['district'];
        $data['from_name'] = $fromAddress['name'];
        $data['from_mobile'] = $fromAddress['mobile'];
        $data['from_address'] = str_replace(["\t", "\r\n", "\r", "\n", " "], '', $fromAddress['address']);
        $data['from_poi'] = $fromAddress['poi'];
        $data['from_lng'] = $fromAddress['lng'];
        $data['from_lat'] = $fromAddress['lat'];
        $data['from_first_code'] = empty($fromCode['first_code'])?'':$fromCode['first_code'];
        $data['from_second_code'] = empty($fromCode['second_code'])?'':$fromCode['second_code'];

        $data['to_address_id'] = $toAddress['id'];
        $data['to_province'] = $toAddress['province'];
        $data['to_city'] = $toAddress['city'];
        $data['to_district'] = $toAddress['district'];
        $data['to_name'] = $toAddress['name'];
        $data['to_mobile'] = $toAddress['mobile'];
        $data['to_address'] = str_replace(["\t", "\r\n", "\r", "\n", " "], '', $toAddress['address']);
        $data['to_poi'] = $toAddress['poi'];
        $data['to_lng'] = $toAddress['lng'];
        $data['to_lat'] = $toAddress['lat'];
        $data['to_first_code'] = empty($toCode['first_code'])?'':$toCode['first_code'];
        $data['to_second_code'] = empty($toCode['second_code'])?'':$toCode['second_code'];
        $data['goods_type'] = $goods_type;
        $data['weight'] = $weight;
        $data['b_price'] = $b_price;    //保价支付金额
        $data['b_true_price'] = $b_true_price;      //物品价格
        $data['tips_price'] = $tips_price;
        $data['note'] = $note;
        $data['nextsendtime'] = time();

        #地址验证 start#
        if(!\addons\paotui\service\UserAddress::checkCity($data['from_city'])){
            $this->error("当前选择位置不在运营范围内！");
        }

        if(!\addons\paotui\service\UserAddress::checkCity($data['to_city'])){
            $this->error("当前选择位置不在运营范围内！");
        }
        #地址验证 end#

        #预约 start#

        $data['is_appoints'] = $is_appoints;
        $data['appoints_day'] = $appoints_day;
        $data['appoints_time'] = $appoints_time;

        if($is_appoints){
            if(empty($data['appoints_day']) || empty($data['appoints_time'])){
                $this->error("请选择预约时间");
            }
        }else{
            unset($data['appoints_day']);
            unset($data['appoints_time']);
        }
        #预约 end#

        #获取收发件经纬度之间的距离 米 start#

        $postService = new \addons\paotui\service\Post();
        $commonPrice = $postService->getPostDetailPrice($from_address_id,$to_address_id,$this->auth->id,$type,$weight);
        if(!$commonPrice){
            $this->error($postService->error);
        }

        $data['distance'] = $commonPrice['distance'];
        $data['general_price'] = $commonPrice['general_price'];
        $data['over_distance'] = $commonPrice['over_distance'];
        $data['over_distance_price'] = $commonPrice['over_distance_price'];
        $data['over_weight_price'] = $commonPrice['over_weight_price'];
        $data['over_weight'] = $commonPrice['over_weight'];
        $data['extra_price'] = $commonPrice['extra_price'];
        $data['extra_node'] = $commonPrice['extra_node'];

        $total_price = bcadd($data['general_price'],$data['b_price'],2);    //基础费用+保价费用
        $total_price = bcadd($total_price,$data['tips_price'],2);           //小费
        $total_price = bcadd($total_price,$data['over_distance_price'],2);  //超出里程费用
        $total_price = bcadd($total_price,$data['over_weight_price'],2);    //超出重量费用
        $total_price = bcadd($total_price,$data['extra_price'],2);          //溢价
        $data['total_price'] = $total_price;        //原始价格

        if(isset($commonPrice['discount_price'])){
            //如果有折扣价，计算折扣价,折扣价格中包含超重和超距离费用
            $pay_price = bcadd($commonPrice['discount_price'],$data['b_price'],2);    //折扣价格+保价费用
            $pay_price = bcadd($pay_price,$data['tips_price'],2);           //小费
            $pay_price = bcadd($pay_price,$data['extra_price'],2);          //溢价
        }else{
            $pay_price = bcadd($data['general_price'],$data['b_price'],2);    //基础费用+保价费用
            $pay_price = bcadd($pay_price,$data['tips_price'],2);           //小费
            $pay_price = bcadd($pay_price,$data['over_distance_price'],2);  //超出里程费用
            $pay_price = bcadd($pay_price,$data['over_weight_price'],2);    //超出重量费用
            $pay_price = bcadd($pay_price,$data['extra_price'],2);          //溢价
        }

        $data['pay_price'] = $pay_price;      //实际支付价格

        #获取佣金 start#
        if(isset($commonPrice['discount_price'])){
            $allow_brokerage_price = bcadd($commonPrice['discount_price'],$data['tips_price'],2);           //小费
            $allow_brokerage_price = bcadd($allow_brokerage_price,$data['extra_price'],2);          //溢价
        }else{
            $allow_brokerage_price = bcadd($data['general_price'],$data['tips_price'],2);           //小费
            $allow_brokerage_price = bcadd($allow_brokerage_price,$data['over_distance_price'],2);  //超出里程费用
            $allow_brokerage_price = bcadd($allow_brokerage_price,$data['over_weight_price'],2);    //超出重量费用
            $allow_brokerage_price = bcadd($allow_brokerage_price,$data['extra_price'],2);          //溢价
        }

        $data['brokerage']=$allow_brokerage_price;

        #获取佣金 end#

        #获取收发件经纬度之间的距离 米 end#
        $msg = [
            'from_address_id.require' => '请选择发件地址',
            'to_address_id.require' => '请选择收件地址',
            'goods_type.require' => '请选择物品类型',
            'weight.require' => '请填写物品重量'
        ];

        $rule = [
            'from_address_id'  => 'require',
            'to_address_id'  => 'require',
            'goods_type'=>'require',
            'weight'=>'require',
        ];

        $validate = new Validate($rule, $msg);
        $result = $validate->check($data);
        if (!$result) {
            $this->error(__($validate->getError()), null,[]);
        }

        $postService = new \addons\paotui\service\Post();
        if($result = $postService->addPost($data)){
            $this->success('提交成功',['order_no'=>(string)$result->order_no]);
        }else{
            $this->error('提交失败');
        }

    }

    /**
     * 支付订单
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function pay(){

        $info = get_addon_info('epay');
        if(empty($info) || $info['state'] == 0){
            $this->error('请到后台插件管理安装《微信支付宝整合》插件');
        }

        $order_no = $this->request->post('order_no');
        $postModel = new \app\admin\model\paotui\Post();
        $postInfo = $postModel->where(['order_no'=>$order_no,'user_id'=>$this->auth->id,'pay_status'=>0])->find();
        if(empty($postInfo)){
            $this->error('当前订单不存在或已支付');
        }

        $wechatUser = Third::get(['user_id'=>$this->auth->id]);
        $params = [
            'amount'=>$postInfo['pay_price'],
            'orderid'=>$order_no."_".rand(1000,9999),
            'type'=>"wechat",
            'title'=>"跑腿订单",
            'notifyurl'=>$this->request->domain()."/api/paotui/block/notifyx",
            'method'=>"miniapp",
            'openid'=>$wechatUser['openid']
        ];

        $return =  \addons\epay\library\Service::submitOrder($params);
        if($return){
            $this->success('请求成功',json_decode($return));
        }else{
            $this->error("请求失败");
        }



    }

    /**
     * 取消订单
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function cancel(){
        $order_no = $this->request->post('order_no');

        Db::startTrans();
        $postModel = new \app\admin\model\paotui\Post();
        $postInfo = $postModel->lock(true)->where(['order_no'=>$order_no,'user_id'=>$this->auth->id,'status'=>['in',[1,2,3]]])->find();
        if(empty($postInfo)){
            $this->error('当前订单不存在或不可以取消');
        }

        if($postInfo->save(['status'=>-1,'canceltime'=>time()])){

            if($postInfo['pay_price'] >0 ){
                if($postInfo['status'] == 2 || $postInfo['status'] == 3){
                    //退款,原路退回
                    try {
                        $config = \addons\epay\library\Service::getConfig('wechat');

                        $config['app_id'] = $config['miniapp_id'];
                        $pay = Pay::wechat($config);
                        $param = [
                            'transaction_id'=>$postInfo['transaction_id'],
                            'out_refund_no'=>time()."_".rand(1000,9999),
                            'total_fee' => $postInfo['pay_price']*100,
                            'refund_fee'=> $postInfo['pay_price']*100,
                            'refund_desc'=>"退款"
                        ];

                        $result = $pay->refund($param);
                        if($result->result_code == "SUCCESS"){

                            if($postInfo['status'] == 3){
                                //生成socket记录
                                $postSocketModel = new PostSocket();
                                $postSocketInfo = $postSocketModel->where(['post_id'=>$postInfo['id']])->find();
                                if($postSocketInfo){
                                    $postSocketInfo->save(['type'=>4,'poster_id'=>$postInfo['poster_id'],'distance'=>0,'send_num'=>0,'next_send_time'=>time(),'send_status'=>0]);
                                }else{
                                    $postSocketModel = new PostSocket();
                                    $postSocketModel->save(['type'=>4,'post_id'=>$postInfo['id'],'poster_id'=>$postInfo['poster_id'],'distance'=>0,'send_num'=>0,'next_send_time'=>time(),'send_status'=>0]);
                                }
                            }
                            Db::commit();
                            $this->success();
                        }
                    }catch (\Yansongda\Pay\Exceptions\Exception $e){
                        Db::rollback();
                        $this->error("退款申请失败，请联系客服");
                    }
                }
            }
        }else{
            Db::rollback();
            $this->error("请求失败");

        }
    }

    /**
     * 删除订单
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function del(){
        $order_no = $this->request->post('order_no');
        $postModel = new \app\admin\model\paotui\Post();
        $postInfo = $postModel->where(['order_no'=>$order_no,'user_id'=>$this->auth->id,'status'=>-1])->find();
        if(empty($postInfo)){
            $this->error('当前订单不存在或不可以删除');
        }

        if($postInfo->save(['is_delete'=>1,'deletetime'=>time()])){
            $this->success("请求成功");
        }else{
            $this->error("请求失败");

        }
    }
}
